Hash Function(雜湊函數) 可以把任意長度的資料,經過一連串運算後,轉換成固定長度的輸出。
任意長度的資料
↓
Hash Function
↓
固定長度的 Hash
常見的 Hash 演算法有:
MD5
SHA-1
SHA-256
SHA-512
不同的演算法會產生不同長度的 Hash:
MD5 → 128 bits
SHA-1 → 160 bits
SHA-256 → 256 bits
SHA-512 → 512 bits
例如 SHA-256 會產生 256 bits,也就是 64 個十六進位字元。
Hello
↓
SHA-256
↓
185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
只要輸入資料完全相同,使用相同的 Hash 演算法,就會得到相同的 Hash。
光看例子可能沒什麼感覺,我們可以自己算一次。
先建立一個 test.txt,內容輸入:
Hello

接著開啟 Windows PowerShell,輸入:
Get-FileHash .\test.txt -Algorithm SHA256
你會看到:

先把這組 Hash 記下來。
接著,回去test.txt修改任一個字,像是:
Hello
↓
Hallo

然後再執行一次:
Get-FileHash .\test.txt -Algorithm SHA256
你會發現:
Hello → 185F8DB32271FE25F561A6FC938B2E264306EC304EDA518007D1764826381969
Hallo → 753692EC36ADB4C794C973945EB2A99C1649703EA6F76BF259ABB4FB838E013E

明明只改了一個字元,最後的 Hash 卻完全不同。
這是 Hash 很重要的特性之一。
為什麼只改一個字,Hash 卻會產生這麼大的變化?
這是因為 Hash Function 會經過多次的位元運算與資料混合,讓輸入中的微小變化擴散到最後的輸出。
因此:
輸入資料只要發生一點點變化,輸出的 Hash 就可能產生非常大的變化。
這種特性稱為 Avalanche Effect(雪崩效應)。
如果兩份不同的資料,卻得到相同的 Hash,就稱為 Hash Collision(雜湊碰撞)。
為什麼會有碰撞?
因為輸入資料可以是任意長度,但 Hash 的輸出長度是固定的。
以 SHA-256 為例,不管輸入是一個字、一張照片,還是一個幾 GB 的檔案,最後產生的結果都只有 256 bits。
因此,從數學上來說,不同的輸入一定有可能得到相同的 Hash。
碰撞攻擊(Collision Attack)就是刻意尋找兩份不同的資料,讓它們產生相同的 Hash。
例如:
檔案 A → SHA-1 → ABC123...
檔案 B → SHA-1 → ABC123...
如果攻擊者能夠做到這件事,就可能利用 Hash 的特性進行攻擊。
例如某個系統只檢查檔案的 Hash,就可能把「原本可信的檔案」和「被攻擊者準備的另一份檔案」混淆。
MD5 和 SHA-1 都曾被認為具有足夠的碰撞抵抗能力,但研究人員後來找到能有效利用其弱點的方法,成功產生具有相同 Hash 的不同資料。
因此,MD5 和 SHA-1 現在都不適合用在需要強碰撞抵抗能力的安全用途。
相較之下,SHA-256、SHA-512 目前是更常見的選擇。
Hash 和 Encryption 很容易被搞混。
Hash:
資料
↓
Hash
通常是單向的,不能直接從 Hash 還原原始資料。
Encryption:
明文
↓
加密 + Key
↓
密文
↓
解密 + Key
↓
明文
Hash 就像資料的指紋。
當資料內容改變時,Hash 也會跟著改變,所以可以用來驗證檔案是否被修改過。